
#include "rtc_calendar.h"


//判断是否是闰年函数
//输入:年份
//输出:该年份是不是闰年.1,是.0,不是
u8 IS_Leap_Year( u16 year )
{
    //能被4或者400整除，并且不能被100整除
    if( ( ( year % 4 == 0 ) || ( year % 400 == 0 ) ) && ( year % 100 != 0 ) )
        return 1;
    else
        return 0;

}
//设置时钟
//把输入的时钟转换为秒钟
//以1970年1月1日为基准
//1970~2099年为合法年份
//返回值:0,成功;其他:错误代码.
//月份数据表
u8 const table_week[12] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5}; //月修正数据表
//平年的月份日期表
const u8 mon_table[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
u8 RTC_Set( u16 syear, u8 smon, u8 sday, u8 hour, u8 min, u8 sec )
{
    u16 t;
    u32 seccount = 0;
    if( syear < 1970 || syear > 2099 )
        return 1;
    for( t = 1970; t < syear; t++ )                //所有年份的秒钟相加
    {
        if( IS_Leap_Year( t ) )
            seccount += 31622400;                  //闰年秒钟数
        else
            seccount += 31536000;                  //平年秒钟数
    }
    smon -= 1;
    for( t = 0; t < smon; t++ )                    //把前面月份的秒钟数相加
    {
        seccount += ( u32 )mon_table[t] * 86400;
        if( IS_Leap_Year( syear ) && t == 1 )            //闰年2月份增加一天的秒钟数
            seccount += 86400;
    }
    seccount += ( u32 )( sday - 1 ) * 86400;          //把前面天数的秒钟数相加
    seccount += ( u32 )hour * 3600;                //加小时秒钟数
    seccount += ( u32 )min * 60;                   //加分钟秒钟数
    seccount += sec;                         //加上最后的秒数

    RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE );
    PWR_BackupAccessCmd( ENABLE );

    RTC_SetCounter( seccount );                    //设置RTC计数器的值
    RTC_WaitForLastTask();
    return 0;
}
//初始化闹钟
//以1970年1月1日为基准
//1970~2099年为合法年份
//syear,smon,sday,hour,min,sec：闹钟的年月日时分秒
//返回值:0,成功;其他:错误代码.
u8 RTC_Alarm_Set( u16 syear, u8 smon, u8 sday, u8 hour, u8 min, u8 sec )
{
    u16 t;
    u32 seccount = 0;
    if( syear < 1970 || syear > 2099 )
        return 1;
    for( t = 1970; t < syear; t++ )                //所有年份的秒钟相加
    {
        if( IS_Leap_Year( t ) )
            seccount += 31622400;                  //闰年秒钟数
        else
            seccount += 31536000;                  //平年秒钟数
    }
    smon -= 1;
    for( t = 0; t < smon; t++ )                    //把前面月份的秒钟数相加
    {
        seccount += ( u32 )mon_table[t] * 86400;
        if( IS_Leap_Year( syear ) && t == 1 )            //闰年2月份增加一天的秒钟数
            seccount += 86400;
    }
    seccount += ( u32 )( sday - 1 ) * 86400;          //把前面天数的秒钟数相加
    seccount += ( u32 )hour * 3600;                //加小时秒钟数
    seccount += ( u32 )min * 60;                   //加分钟秒钟数
    seccount += sec;                         //加上最后的秒数

    RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE );
    PWR_BackupAccessCmd( ENABLE );

    RTC_SetAlarm( seccount );
    RTC_WaitForLastTask();

    return 0;
}
//得到当前的时间
//返回值:0,成功;其他:错误代码.
u8 RTC_Get( void )
{
    static u16 daycnt = 0;
    u32 timecount = 0;
    u32 temp = 0;
    u16 temp1 = 0;
    timecount = RTC_GetCounter();
    temp = timecount / 86400;                   //得到天数 小于1天时，秒小于86400

    if( daycnt != temp )
    {
        daycnt = temp;
        temp1 = 1970;
        while( temp > 365 )                        //超过1年
        {
            if( IS_Leap_Year( temp1 ) )                  //闰年
            {
                if( temp > 366 )
                {
                    temp -= 366;
                }
                else
                {
                    temp1++;
                    break;
                }
            }
            else                             //平年
            {
                temp -= 365;
            }
            temp1++;
        }
        calendar.w_year = temp1;                //得到年份
        temp1 = 0;
        while( temp >= 28 )                        //超过1月
        {
            if( IS_Leap_Year( calendar.w_year ) && temp1 == 1 )
            {
                if( temp >= 29 )
                    temp -= 29;
                else
                    break;
            }
            else
            {
                if( temp >= mon_table[temp1] )
                    temp -= mon_table[temp1];
                else
                    break;
            }
            temp1++;
        }
        calendar.w_month = temp1 + 1;              //月
        calendar.w_date = temp + 1;                //日
    }
    temp = timecount % 86400;
    calendar.hour = temp / 3600;
    calendar.min = ( temp % 3600 ) / 60;
    calendar.sec = ( temp % 3600 ) % 60;
    calendar.week = RTC_Get_Week( calendar.w_year, calendar.w_month, calendar.w_date );
    return 0;
}
//获得现在是星期几
//功能描述:输入公历日期得到星期(只允许1901-2099年)
//输入参数：公历年月日
//返回值：星期号
u8 RTC_Get_Week( u16 year, u8 month, u8 day )
{
    u16 tem;
    u8 yearH, yearL;
    yearH = year / 100;
    yearL = year % 100;
    if( yearH > 19 )
        yearL += 100;
    tem = yearL + yearL / 4;
    tem = tem % 7;
    tem = tem + day + table_week[month - 1];
    if( yearL % 4 == 0 && month < 3 )
        tem--;
    return tem % 7;
}
